#pragma once
#include <iostream>
#include <unordered_map>
#include <string>
#include <vector>
#include <fstream>
#include <cassert>
#include <algorithm>
#include "../comm/commfun.hpp"
#include "../comm/log.hpp"

using namespace std;
using namespace ns_commfunc;

namespace ns_model
{

    struct Question
    {
        string number;
        string title;
        string star;
        int cpu_limit;
        int mem_limit;

        string desc;
        string header;
        string tail;
        Question() {
            
        }
        Question(const Question& q) {
            cpu_limit = q.cpu_limit;
            mem_limit = q.mem_limit;
            number = q.number;
            star = q.star;
            title = q.title;
            desc = q.desc;
            header = q.header;
            tail = q.tail;
        }
    };

    const string queslist_path = "./questions/questionslist.txt";
    const string ques_path = "./questions/";

    class model
    {
    private:
        //将题目信息加载进内存
        unordered_map<string, Question> questions;
    public:
        model()
        {
            assert(LoadQuestions(queslist_path));
        }

        ~model(){}

        //获取整个题库
        bool GetQuestions(vector<Question>& ques)
        {
            if(questions.size() == 0) return false;

            for(auto& q : questions)
            {
                //获取
                ques.push_back(q.second);
            }

            //对题库进行排序
            sort(ques.begin(), ques.end(), [](const Question& q1, const Question& q2){
               return stoi(q1.number) < stoi(q2.number); 
            });
            return true;
        }

        bool GetOneQuestion(string& number, Question& ques)
        {
            auto it = questions.find(number);
            if(it == questions.end()) return false;

            ques = it->second;
            std::cout <<it->second.number << std::endl;
            std::cout << it->second.star << std::endl;
            std::cout <<it->second.title << std::endl;
            std::cout <<it->second.desc << std::endl;
            std::cout <<it->second.header << std::endl;
            return true;
        }

        bool LoadQuestions(const string& filepath)
        {
            ifstream in(filepath);
            if(!in.is_open())
            {
                Log(Fatal, "questionlist file open file");
                return false;
            }

            string line;
            while(getline(in, line))
            {
                vector<string> vs;
                StringUtil::SplitStr(line, vs, " ");
                if(vs.size() != 5) continue;

                Question temp;
                temp.number = vs[0];
                temp.title = vs[1];
                temp.star = vs[2];
                temp.cpu_limit = stoi(vs[3]);
                temp.mem_limit = stoi(vs[4]);

                string path = ques_path + temp.number;
                //std::cout << path << std::endl;
                FileUtil::Readfile(path + "/desc.txt", temp.desc, true);
                FileUtil::Readfile(path + "/header.cpp", temp.header, true);
                FileUtil::Readfile(path + "/tail.cpp", temp.tail, true);
                std::cout <<temp.number << std::endl;
                std::cout << temp.star << std::endl;
                std::cout <<temp.title << std::endl;
                std::cout <<temp.desc << std::endl;
                std::cout <<temp.header << std::endl;

                questions.insert({temp.number, temp});
            }

            in.close();

            Log(Info, "Load success");
            return true;
        }

    };
}
